<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/4/11
 * Time: 18:14
 */

namespace app\common\lib\util;

use think\Db;

class RpcClient
{
    static private $error;
    static private $config;
    
    static public function config($config=[]){
        if(empty($config)){
            if(config('local_debug')){
                self::$config=[
                    'url'=>'http://dc.miyuhaiwai.my_online/Rpc',
                    //'classPath'=>'common\\lib\\model\\',
                    'clientId'=>102
                ];
            }else{
                self::$config=[
                    'url'=>'http://dc.miyuhaiwai.com/Rpc',
                    //'classPath'=>'common\\lib\\model\\',
                    'clientId'=>102
                ];
            }

        }else{
            self::$config=$config;
        }
    }
    static public function call($class,$method,$args){
        if(empty(self::$config))self::config();
        $data=[
            'class'=>ucfirst($class),
            'method'=>$method,
            'args'=>json_encode($args,true),
            'clientId'=>self::$config['clientId']
        ];
        $sign=self::sign($data);
        $data['sign']=$sign;
        $rs=self::http(self::$config['url'],$data);
        return $rs;
    }
    static private function sign($data){
        $clientId=$data['clientId'];
        $args=$data['args'];
        $class=$data['class'];
        $method=$data['method'];

        $secret=self::getSecret($clientId);
        $str='args='.$args.'&clientId='.$clientId.'&class='.$class.'&clientId='.$clientId.'&method='.$method.'&key='.$secret;
        $sign=strtolower(md5($str));
        return $sign;
    }

    static private function http($url,$data){
        $rs=self::_http($url,$data,'POST',array("Content-Type:application/x-www-form-urlencoded;charset=UTF-8"));

        $arr=json_decode($rs,true);
        if(is_null($arr)){
            self::$error='返回格式错误:'.$rs;
            return false;
        }
        if(1==$arr['result']){
            return $arr['data'];
        }else{
            self::$error=$arr['msg'];
            return false;
        }
    }

    static private function getSecret($clientId){
        try{
            $rs=Db::name('client_node')->where(['client_id'=>$clientId])->cache('client_node:'.$clientId)->find();
            return $rs['secret'];
        }catch (\Exception $e){
            self::$error=$e->getMessage();
            return false;
        }
    }

    static public function getError(){
        return self::$error;
    }

    static private function _http($url, $params, $method = 'GET', $header = array(), $multi = false){
        $opts = array(
            CURLOPT_TIMEOUT        => 10,
            CURLOPT_RETURNTRANSFER => 1,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => false,
            //CURLOPT_HTTPHEADER     => $header,
            //CURLOPT_HEADER => 0
        );
        /* 根据请求类型设置特定参数 */
        switch(strtoupper($method)){
            case 'GET':
                if(empty($params)){
                    $getUrl=$url;
                }else{
                    $query=http_build_query($params);
                    if(strpos($url,'?')){
                        if(substr($url,-1)=='&'){
                            $getUrl=$url.$query;
                        }else{
                            $getUrl=$url.'&'.$query;
                        }
                    }else{
                        $getUrl=$url.'?'.$query;
                    }
                }
                $opts[CURLOPT_URL] = $getUrl;
                break;
            case 'POST':
                //判断是否传输文件
                $params = $multi ? $params : http_build_query($params);
                $opts[CURLOPT_URL] = $url;
                $opts[CURLOPT_POST] = 1;
                $opts[CURLOPT_POSTFIELDS] = $params;
                break;
            default:
                self::$error='不支持的请求方式';
                return false;
        }
        /* 初始化并执行curl请求 */
        $ch = curl_init();
        curl_setopt_array($ch, $opts);
        $data  = curl_exec($ch);
        $error = curl_error($ch);
        curl_close($ch);

        if($error){
            self::$error='请求发生错误';
            return false;
        }
        return  $data;
    }

}
